package com.platform.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.platform.base.domain.*;
import com.platform.base.mapper.BaseLocationMapper;
import com.platform.base.mapper.CollectorInfoMapper;
import com.platform.base.mapper.UnitValveInfoMapper;
import com.platform.base.mapper.ValveTypeMapper;
import com.platform.base.service.IUnitValveInfoService;
import com.platform.common.constant.UserConstants;
import com.platform.common.core.text.Convert;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.DateUtils;
import com.platform.common.utils.StringUtils;
import com.platform.common.utils.netty.NettyUtil;
import com.platform.common.utils.rabbit.RabbitUtils;
import com.platform.common.utils.redis.RedisRun;
import com.platform.common.utils.redis.RedisUtil;
import org.apache.shiro.codec.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 阀门信息Service业务层处理
 * 
 * @author wangqi
 * @date 2020-09-25
 */
@Service
public class UnitValveInfoServiceImpl extends ServiceImpl<UnitValveInfoMapper,UnitValveInfo> implements IUnitValveInfoService
{
    @Autowired
    private UnitValveInfoMapper unitValveInfoMapper;
    @Autowired
    private CollectorInfoMapper collectorInfoMapper;

    @Autowired
    private ValveTypeMapper valveTypeMapper;

    @Autowired
    private BaseLocationMapper baseLocationMapper;


    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RabbitUtils rabbitUtils;

    /**
     * 查询热信息列表
     *
     * @param locationId 热信息
     * @return 热信息
     */
    @Override
    public List<UnitValveInfo> selectUnitValveInfoBylocationId(String locationId)
    {
        return unitValveInfoMapper.selectUnitValveInfoBylocationId(locationId);
    }

    /**
     * 查询热信息列表
     *
     * @param collectorId 热信息
     * @return 热信息
     */
    @Override
    public List<UnitValveInfo> selectUnitValveInfoBycollectorId(String collectorId)
    {
        return unitValveInfoMapper.selectUnitValveInfoBycollectorId(collectorId);
    }
    /**
     * 查询热信息列表
     *
     * @return 热信息
     */
    @Override
    public List<UnitValveInfo> selectCollectorInfoEq()
    {
        return unitValveInfoMapper.selectCollectorInfoEq();
    }

    /**
     * 查询阀门信息列表
     * 
     * @param unitValveInfo 阀门信息
     * @return 阀门信息
     */
    @Override
    public List<UnitValveInfo> selectUnitValveInfoList(UnitValveInfo unitValveInfo)
    {
        return unitValveInfoMapper.selectUnitValveInfoList(unitValveInfo);
    }

    /**
     * 查询阀门信息
     *
     * @param valveId 阀门Id
     * @return 阀门信息集合
     */
    @Override
    public UnitValveInfo selectUnitValveInfoById(String valveId){
        UnitValveInfo unitValveInfo = unitValveInfoMapper.selectUnitValveInfoById(valveId);
        return unitValveInfo;
    }

    /**
     * 新增阀门信息
     * 
     * @param unitValveInfo 阀门信息
     * @return 结果
     */
    @Override
    public int insertUnitValveInfo(UnitValveInfo unitValveInfo)
    {
        unitValveInfo.setCreateTime(DateUtils.getNowDate());
        return unitValveInfoMapper.insert(unitValveInfo);
    }

    /**
     * 修改阀门信息
     * 
     * @param unitValveInfo 阀门信息
     * @return 结果
     */
    @Override
    public int updateUnitValveInfo(UnitValveInfo unitValveInfo)
    {
        unitValveInfo.setUpdateTime(DateUtils.getNowDate());
        return unitValveInfoMapper.updateById(unitValveInfo);
    }

    /**
     * 删除阀门信息对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteUnitValveInfoByIds(String ids)
    {
        return unitValveInfoMapper.deleteUnitValveInfoByIds(Convert.toStrArray(ids));
    }

  /*  *//**
     * 根据采集器ID更新阀门登记状态
     *
     * @param collectorId 采集器信息
     * @return 结果
     *//*
    @Override
    public int updateUnitValveInfoByCollectorId(String collectorId){
        return unitValveInfoMapper.updateUnitValveInfoByCollectorId(collectorId);
    }*/

    /**
     * 校验阀门是否唯一
     *
     * @param unitValveInfo 阀门信息
     * @return 结果
     */
    @Override
    public String checkUnitValveUnique(UnitValveInfo unitValveInfo){
        UnitValveInfo info = unitValveInfoMapper.selectById(unitValveInfo.getValveId());
        if (StringUtils.isNotNull(info))
        {
            return UserConstants.VALVE_ID_NOT_UNIQUE;
        }
        return UserConstants.VALVE_ID_UNIQUE;
    }

    /**
     * 导入采集器信息数据
     *
     * @param infoList 采集器信息数据
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importInfo(List<UnitValveInfo> infoList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(infoList) || infoList.size() == 0)
        {
            throw new BusinessException("导入阀门信息数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (UnitValveInfo info : infoList)
        {
            try
            {
                //查询阀门类型信息
                ValveType type = null;
                if(info.getTypeName()!=null && !info.getTypeName().equals("")){
                    List<ValveType> list = valveTypeMapper.selectList(new QueryWrapper<ValveType>().eq("type_name", info.getTypeName()));
                    if(list!=null && list.size()>0){
                        type = list.get(0);
                        info.setTypeId(type.getTypeId());
                    }else{
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 阀门类型不存在");
                        continue;
                    }
                }
                //查询采集器地址信息
                BaseLocation location = null;
                if(info.getLocationName()!=null && !info.getLocationName().equals("")){
                    List<BaseLocation> list = baseLocationMapper.selectList(new QueryWrapper<BaseLocation>().eq("location_name", info.getLocationName()));
                    if(list!=null && list.size()>0){
                        location = list.get(0);
                        info.setLocationId(location.getLocationId());
                    }
                }
                // 校验采集器是否存在
                UnitValveInfo f = unitValveInfoMapper.selectById(info.getValveId());
                if (StringUtils.isNull(f))
                {
                    info.setCreateBy(operName);
                    info.setCreateTime(DateUtils.getNowDate());
                    this.insertUnitValveInfo(info);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    info.setUpdateBy(operName);
                    info.setUpdateTime(DateUtils.getNowDate());
                    this.updateUnitValveInfo(info);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、阀门 " + info.getValveId() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }


    /**
     * 设置阀门开度
     * @param valveIds 阀门信息
     * @param hex 阀门开度值
     * @return
     * @throws Exception
     */
    @Override
    public String apertureInfo(String[] valveIds, String hex) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));

            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "54";

            //控制码
            String cont = "15";

            String zh = NettyUtil.get16HexNum((NettyUtil.get10HexNum(hex)  * 10) / 256);
            if(zh.length()<2){
                zh = "0" + zh;
            }else{
                zh = zh.substring(zh.length()-2);
            }
            String zl = NettyUtil.get16HexNum((NettyUtil.get10HexNum(hex)  * 10) % 256);
            if(zl.length()<2){
                zl = "0" + zl;
            }else{
                zl = zl.substring(zl.length()-2);
            }
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(zh)+NettyUtil.get10HexNum(zl);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + zh+ " "   + zl + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "设置阀门开度");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(!result.equals("00")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 设置阀门开度失败");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 设置阀门开度成功");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，设置阀门开度失败！共 " + failureNum + " 条设置阀门开启失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门已全部设置阀门开度成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }



    /**
     * 读取阀门数据
     * @param valveIds 阀门信息
     * @return
     * @throws Exception
     */
    @Override
    public String checkInfo(String[] valveIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));
            //控制码
            String cont = "14";
            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "51";
            //字节数
            String zjs = "0E";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(zjs);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + "00 "  + zjs + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "读取阀门数据");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(!result.equals("00")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 读取失败");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 读取成功");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，阀门读取失败！共 " + failureNum + " 条阀门读取失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门数据读取成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }


    /**
     * PID参数是远程修改
     * @param valveIds 阀门信息
     * @return
     * @throws Exception
     */
    @Override
    public String pidsInfo(String[] valveIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));
            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "81";

            //控制码
            String cont = "15";
            //控制码
            String hex = "01";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + "00 "  + hex + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "打开PID参数远程修改");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(result.equals("00") || result.equals("01")){
                info.setRegisterS("1");

                info.setUpdateTime(DateUtils.getNowDate());
                unitValveInfoMapper.updateById(info);
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 打开PID参数远程修改成功");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 打开PID参数远程修改成功");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，阀门打开PID参数远程修改失败！共 " + failureNum + " 条阀门打开PID参数远程修改失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门打开PID参数远程修改成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
    /**
     * PID参数否远程修改
     * @param valveIds 阀门信息
     * @return
     * @throws Exception
     */
    @Override
    public String pidsfInfo(String[] valveIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));
            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "81";

            //控制码
            String cont = "15";
            //控制码
            String hex = "00";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + "00 "  + hex + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "关闭PID参数远程修改");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(result.equals("00") || result.equals("02")){
                info.setRegisterS("0");

                info.setUpdateTime(DateUtils.getNowDate());
                unitValveInfoMapper.updateById(info);
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 关闭PID参数远程修改成功");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 关闭PID参数远程修改成功");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，阀门关闭PID参数远程修改失败！共 " + failureNum + " 条阀门关闭PID参数远程修改失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门关闭PID参数远程修改成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * PID功能关闭
     * @param valveIds 阀门信息
     * @return
     * @throws Exception
     */
    @Override
    public String pidwfInfo(String[] valveIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));
            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "6E";

            //控制码
            String cont = "15";
            //控制码
            String hex = "00";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + "00 "  + hex + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "关闭PID功能");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(result.equals("00") || result.equals("02")){
                info.setRegisterW("0");
                info.setRegisterS("1");
                info.setUpdateTime(DateUtils.getNowDate());
                unitValveInfoMapper.updateById(info);
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 关闭PID功能");
            }
           else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 关闭PID功能");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，关闭PID功能失败！共 " + failureNum + " 条关闭PID功能失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门关闭PID功能成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
    /**
     * PID功能打开
     * @param valveIds 阀门信息
     * @return
     * @throws Exception
     */
    @Override
    public String pidwInfo(String[] valveIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));
            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "6E";

            //控制码
            String cont = "15";
            //控制码
            String hex = "01";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + "00 "  + hex + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "打开PID功能");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(result.equals("00") || result.equals("02")){
                info.setRegisterW("1");
                info.setRegisterS("1");
                info.setUpdateTime(DateUtils.getNowDate());
                unitValveInfoMapper.updateById(info);
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 打开PID功能");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 打开PID功能");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，阀门打开PID功能修改失败！共 " + failureNum + " 条阀门打开PID功能失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门打开PID功能成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 设置阀门温度
     * @param valveIds 阀门信息
     * @param hex 阀门温度值
     * @return
     * @throws Exception
     */
    @Override
    public String tempInfo(String[] valveIds, String hex) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String valveId : valveIds){
            UnitValveInfo info = null;

            if(redisUtil.hHasKey("unitValve-info", valveId)){
                info = (UnitValveInfo) redisUtil.hget("unitValve-info", valveId);
            }else{
                info = unitValveInfoMapper.selectUnitValveInfoById(valveId);
                redisUtil.hset("unitValve-info", valveId, info, 60000);
            }

            if(info.getCollectorId() == null || info.getCollectorId().equals("")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 未关联采集器");
                continue;
            }

            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", info.getCollectorId());
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(info.getCollectorId());
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(info.getCollectorId());
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + "关联的采集器" + info.getCollectorId() + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = info.getCollectorId().substring(0,2);
            //获取采集器低位
            String cenlow = info.getCollectorId().substring(2,4);
            //阀门
            String fmdz = NettyUtil.get16HexNum(Integer.parseInt(valveId));

            //校验
            String jy = "01";
            //寄存器地址
            String jcq = "6F";

            //控制码
            String cont = "15";

            String zh = NettyUtil.get16HexNum((NettyUtil.get10HexNum(hex)  * 10) / 256);
            if(zh.length()<2){
                zh = "0" + zh;
            }else{
                zh = zh.substring(zh.length()-2);
            }
            String zl = NettyUtil.get16HexNum((NettyUtil.get10HexNum(hex)  * 10) % 256);
            if(zl.length()<2){
                zl = "0" + zl;
            }else{
                zl = zl.substring(zl.length()-2);
            }
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(fmdz)+NettyUtil.get10HexNum(jy)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(jcq)+NettyUtil.get10HexNum(zh)+NettyUtil.get10HexNum(zl);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA " + cenlow + " " + cenhigh + " 00 00 00 00 " + cont + " " + jy + " " + fmdz + " 00 "  + jcq + " " + zh+ " "   + zl + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(info.getCollectorId(), responseStr, "设置阀门温度");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, valveId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            redisUtil.del(valveId);
            if(!result.equals("00")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、阀门 " + info.getValveId() + " 设置阀门温度失败");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、阀门 " + info.getValveId() + " 设置阀门温度成功");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，设置阀门温度失败！共 " + failureNum + " 条设置阀门温度失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，阀门已全部设置阀门温度成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
